<?php
Yii::import('application.vendors.*');
require_once('Zend/Mail.php');
require_once('Zend/Mail/Transport/Smtp.php');

class CronController extends AdminController {
    
    # Перевірка розсилки по створеним через адмінку
    public function actionCheckMailingTasks() {
        $data = Yii::app()->db->createCommand()->select('*')->from('mailer')->where('date<'.time())->queryAll();
        if(!empty($data)) {
            foreach ($data as $item) {
                $mails = explode(',', $data->emails);
                foreach ($mails as $item) {
                    $zendMail = new Zend_Mail();
                    $zendMail->addTo($item, substr($item, 0, strpos($item, '@')));
                    $zendMail->setFrom(Yii::app()->params['email']['emailFrom'], Yii::app()->params['email']['nameFrom']);
                    $zendMail->setSubject($data['subject']);
                    $zendMail->setBodyHtml($data['text']);
                    $zendMail->send(new Zend_Mail_Transport_Smtp('localhost'));
                }
            }
            Yii::app()->db->createCommand()->delete('mailer', 'date<'.time());
        }
    }
    
    # рассылка при создании темы, партнерки, сообщения в теме.
    public function actionCheckAutoMailing() {
        $data = Yii::app()->db->createCommand()->select('type, typeId, childId')->from('mailer_auto')->where(1)->queryAll();
        if(!empty($data)) {
            $partId = $forumId = $forumChildId = $themeId = $themeChildId = array();
            for($i=0; $i<count($data); $i++) {
                if($data[$i]['type'] == 'partner') $partId[] = $data[$i]['typeId'];
                if($data[$i]['type'] == 'forum') {
                    $forumId[] = $data[$i]['typeId'];
                    $forumChildId[] = $data[$i]['childId'];
                }
                if($data[$i]['type'] == 'forum_topic') {
                    $themeChildId[] = $data[$i]['childId'];
                    $themeId[] = $data[$i]['typeId'];
                } 
            }
            if(!empty($partId)) {
                $subscrData = Yii::app()->db->createCommand()->select('s.userId, s.unsId, s.email, u.login')->from('subscribers s')->leftJoin('users u', 'u.userid=s.userId')->where('`type`="partner"')->queryAll();
                if(!empty($subscrData)) {
                    $partners = Yii::app()->db->createCommand()->select('p.name, p.url, p.about, c.name as catName, c.catId, c.parentId')->from('partners p')->join('partners_cat c', 'p.catId=c.catId')->where(array('in', 'partnerid', $partId))->queryAll();
                    $this->sendLetters($partners, $subscrData, 'В Partnerkin.com открыта новая партнерская программа', '//mailing/partner');
                } 
                Yii::app()->db->createCommand()->delete('mailer_auto', '`type`="partner"');
            }
            if(!empty($forumId)) {
                $subscrData = Yii::app()->db->createCommand()->select('s.userId, s.unsId, s.email, u.login, s.typeId')->from('subscribers s')->leftJoin('users u', 'u.userid=s.userId')->where('`type`="forum" and typeId IN('.implode(",", $forumId).')')->queryAll();
                if(!empty($subscrData)) {
                    $forums = Yii::app()->db->createCommand()->select('p.name, p.url, p.partnerid, c.name as catName, c.catId, c.parentId')->from('partners p')->join('partners_cat c', 'p.catId=c.catId')->where('partnerid in(1)')->queryAll();
                    $themes = Yii::app()->db->createCommand()->select('t.title, t.themeId, t.partnerId, u.login, fc.text')->from('forum_theme t')->join('forum_comments fc', 'fc.themeId=t.themeId and fc.isFirst=1')->leftJoin('users u', 'fc.userId=u.userid')->where(array('in', 't.themeId', $forumChildId))->queryAll();
                    for($i=0; $i<count($forums); $i++) {
                        for($l=0; $l<count($themes); $l++) {
                            if($themes[$l]['partnerId'] == $forums[$i]['partnerid']) {
                                $themes[$l]['forumData'] = $forums[$i];
                            }
                        }
                    }
                    $this->sendLetters($themes, $subscrData, 'В мини-форуме на который вы подписаны в Partnerkin.com открыта новая тема', '//mailing/forum'); 
                }
                Yii::app()->db->createCommand()->delete('mailer_auto', '`type`="forum"');
            }
            if(!empty($themeId)) {
                $subscrData = Yii::app()->db->createCommand()->select('s.userId, s.unsId, s.email, u.login, s.typeId')->from('subscribers s')->leftJoin('users u', 'u.userid=s.userId')->where('`type`="forum_topic" and typeId IN('.implode(",", $themeId).')')->queryAll();
                if(!empty($subscrData)) {
                    $themes = Yii::app()->db->createCommand()->select('t.title, t.themeId, p.name, p.url, c.name as catName, c.catId, c.parentId')->from('forum_theme t')->join('partners p','p.partnerid=t.partnerId')->join('partners_cat c', 'p.catId=c.catId')->where(array('in', 'themeId', $themeId))->queryAll();
                    $comments = Yii::app()->db->createCommand()->select('fc.text, fc.themeId, u.login, fc.text')->from('forum_comments fc')->leftJoin('users u', 'fc.userId=u.userid')->where(array('in', 'fc.comId', $themeChildId))->queryAll();
                    for($i=0; $i<count($themes); $i++) {
                        for($l=0; $l<count($comments); $l++) {
                            if($themes[$i]['themeId'] == $comments[$l]['themeId']) {
                                $comments[$l]['theme'] = $themes[$i];
                            }
                        }
                    }
                    $this->sendLetters($comments, $subscrData, 'В 1 из тем на  которое вы подписаны в Partnerkin.com появилось сообщение', '//mailing/theme');
                }
                Yii::app()->db->createCommand()->delete('mailer_auto', '`type`="forum_topic"');
            }
        }
    }
    
    # допоміжна функція для actionCheckAutoMailing
    private function sendLetters($data, $subscrData, $subj, $view) {
        for($i=0; $i<count($data); $i++) {
            for($j=0; $j<count($subscrData); $j++) {
                $zendMail = new Zend_Mail();
                $zendMail->addTo($subscrData[$j]['email'], !empty($subscrData[$j]['login']) ? $subscrData[$j]['login'] : 'Гость');
                $zendMail->setFrom(Yii::app()->params['email']['emailFrom'], Yii::app()->params['email']['nameFrom']);
                $zendMail->setSubject($subj);
                $zendMail->setBodyHtml($this->renderPartial($view, array('subscrData'=>$subscrData[$j], 'data'=>$data[$i]), true));
                $zendMail->send(new Zend_Mail_Transport_Smtp('localhost'));
            }
        }
    }

    # при створенні отзива, чи повідомлення на форумі до партнерки юзер завантажив картинки на сервак, але не відправив отзив - їх ми й видаляемо, щоб не висіли.
    public function actionDelRevImages() {
        $delTime = time() - 18000;
        $revImages = Yii::app()->db->createCommand()->select('bigImg, date')->from('reviews_images')->where('revId=0 and date<'.$delTime)->queryAll();
        foreach ($revImages as $item) {
            if(!empty($item['bigImg']) && file_exists(Yii::getPathOfAlias('webroot').'/images/uploads/reviews/'.$item['bigImg'])) 
                unlink(Yii::getPathOfAlias('webroot').'/images/uploads/reviews/'.$item['bigImg']);
        }
        Yii::app()->db->createCommand()->delete('reviews_images', 'revId=0 and date<'.$delTime);
        $forumImages = Yii::app()->db->createCommand()->select('bigImg, smallImg')->from('forum_images')->where('comId=0 and date<'.$delTime)->queryAll();
        foreach ($forumImages as $item) {
            if(!empty($item['bigImg']) && file_exists(Yii::getPathOfAlias('webroot').'/images/uploads/comments/'.$item['bigImg'])) 
                unlink(Yii::getPathOfAlias('webroot').'/images/uploads/comments/'.$item['bigImg']);
        }
        Yii::app()->db->createCommand()->delete('forum_images', 'comId=0 and date<'.$delTime);
    }
    
    # коли адмін клікне по силці "обновить" ми обновимо рейтинг партнерських програм;
    public function actionUpdatePartnersScoreAdmin() {
        $this->actionUpdatePartnersScore();
        $this->redirect(Yii::app()->request->urlReferrer);
    }
    
//  V - кол-во голосов за партнерку;
//  M - порог голосов, необходимый для участия в рейтинге;
//  R - среднее арифметическое всех голосов за партнерку;
//  С - среднее значение рейтинга всех по параметру!!!!(в тз было написано всех голосов)
//  $raiting = ($V / ($V + $M)) * $R + ($M / ($V + $M) ) * $C; // ще є поняття вага голоса
    
    # рейтинг партнерських програм, вираховую по формулі, що написана вище. 
    public function actionUpdatePartnersScore() {
        $partners = Yii::app()->db->createCommand()->select('partnerId, catId')->from('partners')->queryAll();
        $dataReader = Yii::app()->db->createCommand()->select('val')->from('options')->where('`name`="Порог голосов"')->queryRow();
        $M = $dataReader['val'];
        if(!empty($partners)) {
            for ($i=0; $i<count($partners); $i++) {
                for($j=1;$j<=4;$j++) {
                    $revVotes = Yii::app()->db->createCommand()->select('rat.val, rat.weight')->from('reviews_ratings rat')->join('reviews r', 'r.revId=rat.revId')->where("r.status not in(\"Отклонен\", \"Новый\") and rat.type=$j AND rat.partnerId=".$partners[$i]['partnerId'])->queryAll();
                    if(empty($revVotes)) {
                        $C = 1;
                    } else {
                        $sum = $weight = 0;
                        foreach ($revVotes as $item) {
                            $sum += $item['val'] * $item['weight'];
                            $weight += $item['weight'];
                        }
                        $C = $sum/$weight;
                    }
                    $V = count($revVotes);
                    if($V < $M) {
                        $dataToInsert["field$j"] = 0;
                        continue;
                    }
                    $votes = Yii::app()->db->createCommand()->select('rat.val')->from('reviews_ratings rat')->join('reviews r', 'r.revId=rat.revId')->where('r.status not in("Отклонен", "Новый") and rat.partnerId='.$partners[$i]['partnerId'])->queryAll();
                    if(empty($votes)) {
                        $dataToInsert["field$j"] = 0;
                        continue;
                    }
                    $sum = 0;
                    foreach ($votes as $item) $sum += $item['val'];
                    $R = $sum / count($votes);
                    
                    $dataToInsert["field$j"] = ($V / ($V + $M)) * $R + ($M / ($V + $M) ) * $C;
                }
                
                $sum = 0;
                for($j = 1; $j <= 4; $j++) {
                    $sum += $dataToInsert["field$j"];
                }
                $dataToInsert['mean'] = $sum/4;
                $dataToInsert['partnerId'] = $partners[$i]['partnerId'];
                $dataToInsert['catId'] = $partners[$i]['catId'];
                $V = Yii::app()->db->createCommand()->select('count(*) as count')->from('reviews')->where("`partnerId`=".$partners[$i]['partnerId'])->queryRow();
                $dataToInsert['votes'] = $V['count'];
                
                $record = Yii::app()->db->createCommand()->select('*')->from('partners_cat_score')->where('partnerId='.$partners[$i]['partnerId'])->queryRow();
                if(empty($record)) {
                    Yii::app()->db->createCommand()->insert('partners_cat_score', $dataToInsert);
                } else {
                    Yii::app()->db->createCommand()->update('partners_cat_score', CMap::mergeArray($dataToInsert, array('oldField1'=>$record['field1'],'oldField2'=>$record['field2'],'oldField3'=>$record['field3'],'oldField4'=>$record['field4'], 'oldMean'=>$record['mean'] )), 'partnerId='.$partners[$i]['partnerId']);
                }
            }
        }
    }
    
    # коли адмін клікне по силці "обновить" ми обновимо карму;
    public function actionUpdateUserKarmaAdmin() {
        $this->actionUpdateUserKarma();
        $this->redirect(Yii::app()->request->urlReferrer);
    }
    
    # карма юзера, а точніше "вага" його його голосу, в залежності від карми
    public function actionUpdateUserKarma() {
        $maxLogdate = time() - 86400; # если не заходил больше суток то и нечего грузить запросами сервер(при условии что крон работает раз в сутки)
        $userData = Yii::app()->db->createCommand()->select('regDate as date, userid, weight')->from('users')->where('logDate>'.$maxLogdate)->queryAll();
        $userLevels = Yii::app()->db->createCommand()->select('*')->from('karma_levels')->order('carma asc')->queryAll();
        $karmaKoef = Yii::app()->db->createCommand()->select('*')->from('karma_params')->where('id=1')->queryRow();
        if(!empty($userData) && !empty($userLevels)) {
            foreach ($userData as $user) {
                $res = Yii::app()->db->createCommand()->select('count(*) as count')->from('forum_comments')->where('userId='.$user['userid'])->queryRow();
                $countMessages = $res['count']; # количество сообщений на форуме
                $res = Yii::app()->db->createCommand()->select('count(*) as count')->from('reviews_comments')->where('userId='.$user['userid'])->queryRow();
                $countComents = $res['count']; # количество коментов к отзывам партнерок
                $res = Yii::app()->db->createCommand()->select('count(*) as count')->from('partners_users')->where('userId='.$user['userid'])->queryRow();
                $countPartners = $res['count']; # количество партнерок с которыми он работает
                $res = Yii::app()->db->createCommand()->select('count(*) as count')->from('reviews')->where('userId='.$user['userid'].' and status IN("Сомнительный", "Одобрен")')->queryRow();
                $countReviews = $res['count']; # количество отзывов
                
                $days = round((time() - $user['date']) / 86400); # дни с момента регистрации
                $comDay = round($countComents / $days); # среднее количетсво коментов к отзывам в день
                $mesDay = round($countMessages / $days); # среднее количество сообщений на форуме в день

                if($comDay > 6) $comDayKey = 'comDayMore_6';
                else if($comDay <= 6 && $comDay > 3) $comDayKey = 'comDay_6';
                else if($comDay <= 3 && $comDay > 1.5) $comDayKey = 'comDay_3';
                else if($comDay <= 1.5 && $comDay >= 0) $comDayKey = 'comDay_1_5';
                if($mesDay > 6) $mesDayKey = 'mesDayMore_6';
                else if($mesDay <= 6 && $mesDay > 3) $mesDayKey = 'mesDay_6';
                else if($mesDay <= 3 && $mesDay > 1.5) $mesDayKey = 'mesDay_3';
                else if($mesDay <= 1.5 && $mesDay >= 0) $mesDayKey = 'mesDay_1_5';
                
                $karma = $days * $karmaKoef['timeDays'] + 
                $countMessages * $karmaKoef['mesCount'] + 
                $countPartners * $karmaKoef['partnersCount'] + 
                $countReviews * $karmaKoef['revModer'] +
                $comDay * $karmaKoef[$comDayKey] + 
                $mesDay * $karmaKoef[$mesDayKey];
                
                for ($i = 0; $i < count($userLevels); $i++) {
                    if($karma < $userLevels[0]['carma']) {
                        $weight = 1; break;
                    }  
                    if($karma >= $userLevels[count($userLevels)-1]['carma']) {
                        $weight = $userLevels[count($userLevels)-1]['weight']; break;
                    }
                    if($karma >= $userLevels[$i]['carma'] && $karma <= $userLevels[$i+1]['carma']) 
                        $weight = $userLevels[$i]['weight'];
                }
                if($weight != $user['weight']) 
                    Yii::app()->db->createCommand()->update('users', array('weight'=>$weight), 'userid=:userid', array(':userid'=>$user['userid']));
            }
        }
    }
}